const { sequelize } = require('../library/sequelize');

class ValidationMiddleware {
    constructor() {
        // 用户模型验证规则
        this.userValidation = {
            // 基础格式验证（基于数据库结构）
            basic: {
                name_en: {
                    required: true,
                    type: 'string',
                    maxLength: 50
                },
                name_cn: {
                    required: false,
                    type: 'string',
                    maxLength: 50
                },
                password_text: {
                    required: true,
                    type: 'string',
                    maxLength: 100
                },
                moblie: {
                    required: false,
                    type: 'string',
                    maxLength: 11
                },
                user_type: {
                    required: false,
                    type: 'number',
                    min: 0,
                    max: 10
                },
                is_admin: {
                    required: false,
                    type: 'boolean'
                },
                admin_level: {
                    required: false,
                    type: 'number',
                    min: 0,
                    max: 10
                },
                icon_id: {
                    required: false,
                    type: 'number',
                    min: 0
                },
                openid: {
                    required: false,
                    type: 'string',
                    maxLength: 100
                },
                unionid: {
                    required: false,
                    type: 'string',
                    maxLength: 100
                }
            },

            // 业务规则验证
            business: {
                name_en: {
                    pattern: /^[a-zA-Z0-9_\u4e00-\u9fa5]+$/,
                    message: '用户名只能包含字母、数字、下划线和中文',
                    minLength: 2,
                    messageMinLength: '用户名长度不能少于2个字符'
                },
                password_text: {
                    minLength: 6,
                    pattern: /^(?=.*[A-Za-z])(?=.*\d)/,
                    message: '密码必须包含字母和数字，长度至少6位'
                },
                moblie: {
                    pattern: /^1[3-9]\d{9}$/,
                    message: '手机号格式不正确'
                }
            }
        };

        // 验证器
        this.validators = {
            string: this.validateString.bind(this),
            number: this.validateNumber.bind(this),
            boolean: this.validateBoolean.bind(this)
        };
    }

    /**
     * 用户模型验证中间件
     * @param {string} operation - 操作类型（create, update, query, login, register）
     * @returns {Function} 验证中间件
     */
    validateUser(operation = 'create') {
        return async (req, res, next) => {
            try {
                const errors = [];
                const data = req.body;

                // 根据操作类型调整验证规则
                const adjustedRules = this.adjustRulesForOperation(operation);

                // 第一层：基础格式验证
                const basicErrors = this.validateBasic(data, adjustedRules.basic);
                errors.push(...basicErrors);

                // 第二层：业务规则验证
                const businessErrors = this.validateBusiness(data, adjustedRules.business);
                errors.push(...businessErrors);

                // 如果有错误，返回错误信息
                if (errors.length > 0) {
                    return res.status(400).json({
                        success: false,
                        code: 400,
                        message: '参数验证失败',
                        errors: errors
                    });
                }

                next();
            } catch (error) {
                console.error('用户验证中间件错误:', error);
                res.status(500).json({
                    success: false,
                    code: 500,
                    message: '验证过程发生错误'
                });
            }
        };
    }

    /**
     * 根据操作类型调整验证规则
     */
    adjustRulesForOperation(operation) {
        const basic = { ...this.userValidation.basic };
        const business = { ...this.userValidation.business };

        switch (operation) {
            case 'login':
                // 登录只需要用户名和密码
                Object.keys(basic).forEach(key => {
                    if (key !== 'name_en' && key !== 'password_text') {
                        basic[key].required = false;
                    }
                });
                // 登录时密码验证可以稍微宽松
                delete business.password_text.pattern;
                business.password_text.minLength = 1;
                break;

            case 'register':
                // 注册时用户名和密码必填
                basic.name_en.required = true;
                basic.password_text.required = true;
                break;

            case 'update':
                // 更新时所有字段都不是必填的
                Object.keys(basic).forEach(key => {
                    basic[key].required = false;
                });
                break;

            case 'query':
                // 查询时不需要验证
                return { basic: {}, business: {} };

            default:
                // create 使用默认规则
                break;
        }

        return { basic, business };
    }

    /**
     * 基础格式验证
     */
    validateBasic(data, rules) {
        const errors = [];

        for (const [fieldName, rule] of Object.entries(rules)) {
            const fieldValue = data[fieldName];

            // 检查必填字段
            if (rule.required && (fieldValue === undefined || fieldValue === null || fieldValue === '')) {
                errors.push({
                    field: fieldName,
                    message: `${fieldName} 是必填字段`,
                    value: fieldValue
                });
                continue;
            }

            // 如果字段为空且不是必填，跳过验证
            if (fieldValue === undefined || fieldValue === null || fieldValue === '') {
                continue;
            }

            // 类型验证
            if (rule.type && !this.validators[rule.type](fieldValue)) {
                errors.push({
                    field: fieldName,
                    message: `${fieldName} 类型必须是 ${rule.type}`,
                    value: fieldValue
                });
                continue;
            }

            // 字符串长度验证
            if (rule.type === 'string') {
                if (rule.maxLength && fieldValue.length > rule.maxLength) {
                    errors.push({
                        field: fieldName,
                        message: `${fieldName} 长度不能超过 ${rule.maxLength} 个字符`,
                        value: fieldValue
                    });
                }
            }

            // 数字范围验证
            if (rule.type === 'number') {
                if (rule.min !== undefined && fieldValue < rule.min) {
                    errors.push({
                        field: fieldName,
                        message: `${fieldName} 不能小于 ${rule.min}`,
                        value: fieldValue
                    });
                }

                if (rule.max !== undefined && fieldValue > rule.max) {
                    errors.push({
                        field: fieldName,
                        message: `${fieldName} 不能大于 ${rule.max}`,
                        value: fieldValue
                    });
                }
            }
        }

        return errors;
    }

    /**
     * 业务规则验证
     */
    validateBusiness(data, rules) {
        const errors = [];

        for (const [fieldName, rule] of Object.entries(rules)) {
            const fieldValue = data[fieldName];

            // 如果字段为空，跳过验证
            if (fieldValue === undefined || fieldValue === null || fieldValue === '') {
                continue;
            }

            // 字符串长度验证
            if (rule.minLength && fieldValue.length < rule.minLength) {
                errors.push({
                    field: fieldName,
                    message: rule.messageMinLength || `${fieldName} 长度不能少于 ${rule.minLength} 个字符`,
                    value: fieldValue
                });
            }

            // 正则表达式验证
            if (rule.pattern && !rule.pattern.test(fieldValue)) {
                errors.push({
                    field: fieldName,
                    message: rule.message || `${fieldName} 格式不正确`,
                    value: fieldValue
                });
            }
        }

        return errors;
    }

    /**
     * 字符串验证器
     */
    validateString(value) {
        return typeof value === 'string';
    }

    /**
     * 数字验证器
     */
    validateNumber(value) {
        return typeof value === 'number' && !isNaN(value);
    }

    /**
     * 布尔值验证器
     */
    validateBoolean(value) {
        return typeof value === 'boolean';
    }

    /**
     * 分页参数验证
     */
    validatePagination(req, res, next) {
        const { page, limit, pageSize } = req.body;

        const errors = [];

        if (page !== undefined && (!Number.isInteger(page) || page < 1)) {
            errors.push({
                field: 'page',
                message: '页码必须是大于0的整数',
                value: page
            });
        }

        const size = limit || pageSize;
        if (size !== undefined && (!Number.isInteger(size) || size < 1 || size > 100)) {
            errors.push({
                field: 'limit',
                message: '每页数量必须在1-100之间',
                value: size
            });
        }

        if (errors.length > 0) {
            return res.status(400).json({
                success: false,
                code: 400,
                message: '分页参数验证失败',
                errors: errors
            });
        }

        next();
    }

    /**
     * ID参数验证
     */
    validateId(req, res, next) {
        const { user_id, role_id, id } = req.body;
        const targetId = user_id || role_id || id;

        if (targetId !== undefined && (!Number.isInteger(targetId) || targetId < 1)) {
            return res.status(400).json({
                success: false,
                code: 400,
                message: 'ID必须是大于0的整数',
                errors: [{
                    field: 'id',
                    message: 'ID必须是大于0的整数',
                    value: targetId
                }]
            });
        }

        next();
    }

    /**
     * 搜索参数验证
     */
    validateSearch(req, res, next) {
        const { search } = req.body;

        if (search !== undefined && (typeof search !== 'string' || search.length > 100)) {
            return res.status(400).json({
                success: false,
                code: 400,
                message: '搜索关键词不能超过100个字符',
                errors: [{
                    field: 'search',
                    message: '搜索关键词不能超过100个字符',
                    value: search
                }]
            });
        }

        next();
    }

    /**
     * 排序参数验证
     */
    validateSort(req, res, next) {
        const { sortBy, sortOrder } = req.body;

        const errors = [];

        // 允许的排序字段
        const allowedSortFields = ['user_id', 'name_en', 'name_cn', 'create_time', 'update_time', 'user_type', 'is_admin'];

        if (sortBy !== undefined && !allowedSortFields.includes(sortBy)) {
            errors.push({
                field: 'sortBy',
                message: `排序字段必须是以下之一: ${allowedSortFields.join(', ')}`,
                value: sortBy
            });
        }

        if (sortOrder !== undefined && !['ASC', 'DESC'].includes(sortOrder.toUpperCase())) {
            errors.push({
                field: 'sortOrder',
                message: '排序方向必须是 ASC 或 DESC',
                value: sortOrder
            });
        }

        if (errors.length > 0) {
            return res.status(400).json({
                success: false,
                code: 400,
                message: '排序参数验证失败',
                errors: errors
            });
        }

        next();
    }
}

module.exports = new ValidationMiddleware();